1. Field of the Invention
The present invention relates to compilers for computer systems. More specifically, the present invention relates to a method and an apparatus that non-intrusively gathers code usage information to facilitate removing compiled code in a mixed-mode system that supports execution of both compiled code and interpreter code.
2. Related Art
The exponential growth of the Internet has in part been fueled by the development of computer languages, such as the JAVA(trademark) programming language distributed by Sun Microsystems, Inc. of Palo Alto, Calif. The JAVA programming language allows an application to be compiled into a module containing platform-independent bytecodes, which can be distributed across a network of many different computer systems. Any computer system possessing a corresponding platform-independent virtual machine, such as the JAVA virtual machine, is then able to execute the bytecodes. In this way, a single form of the application can be easily distributed to and executed by a large number of different computing platforms.
When an application is received in platform-independent form, it can be interpreted directly through an interpreter, or alternatively, it can be compiled into machine code for the native architecture of the computing platform. Machine code typically executes significantly faster than interpreter code. However, compiled code occupies considerably more space than interpreter code. Hence, the determination of whether or not to compile interpreter code depends on the relative importance of memory space to execution speed.
Some xe2x80x9cmixed-modexe2x80x9d computer systems support execution of both compiled code and interpreter code. On a mixed-mode system, it is often desirable to eliminate a compiled method in order to free up memory space. However, existing mixed-mode systems can only unload a compiled method when the entire class associated with the compiled method is unloaded. This means that a large number of compiled methods associated with a class can potentially build up in memory before the class is unloaded. This is not a problem in larger computer systems, which have more memory to store compiled methods, and which can rely on the virtual memory system to migrate unused compiled methods to swap space in secondary storage.
However, constrained memory systems, such as pocket-sized computing devices, have limited memory space to accommodate compiled methods, and typically do not provide swap space in secondary storage for the virtual memory system.
Hence, what is needed is a method and an apparatus for removing an unused compiled method from memory without having to wait for the entire class associated with the compiled method to be unloaded.
One embodiment of the present invention provides a system that gathers code usage information to facilitate removing compiled code that has not been recently used. This method operates in a mixed-mode system that supports execution of both compiled code and interpreter code. During operation, the system gathers usage information for compiled methods within an application while the application is executing. Next, the system identifies compiled methods to be removed based on this usage information, and removes identified compiled methods so that interpreter code is executed for the compiled methods instead of compiled code. In this way, the system frees up the memory space used to store the compiled methods.
In a variation on this embodiment, the system is part of a garbage collection mechanism that removes unreachable objects from the memory space of the application in addition to removing compiled methods.
In a variation on this embodiment, gathering the usage information involves keeping track of how many times each compiled method has been garbage collected without being executed. Furthermore, identifying the compiled methods to be removed involves identifying compiled methods that have been garbage collected more than a threshold number of times without being executed.
In a variation on this embodiment, the system keeps track of how many times a given compiled method has been garbage collected by replacing an instruction in the given compiled method with a trap instruction that causes the instruction to be restored to replace the trap instruction when the given method is executed after garbage collection. If the instruction has not been replaced since a preceding garbage collection operation, the system increments a counter associated with the trap instruction so that the counter indicates how many times the given method has been garbage collected without being executed.
In a further variation, the counter is stored in a pointer associated with the trap instruction so that additional memory space is not required to store the counter.
In a variation on this embodiment, if a given compiled method to be removed describes an activation record that is active on the execution stack, the system de-optimizes the activation record, which involves converting the activation record from being described by the given compiled method to being described by the interpreter.
In a variation on this embodiment, if a given compiled method to be removed describes an activation record that is active on the execution stack, the system does not remove the given compiled method, thereby avoiding the expense of de-optimizing the activation record.
In a variation on this embodiment, the system additionally determines a total amount of memory used by compiled methods, and then removes compiled methods if the total amount of memory used by compiled methods exceeds a threshold value.
In a variation on this embodiment, the system additionally determines a total amount of memory used by live user data, and then removes compiled methods if the total amount of memory used by live user data exceeds a threshold value, thereby freeing additional memory space to accommodate live user data.